define(["./utils"], function(utils) {
    var templateRoute = {
            beforeOne: utils.blank,
            before: utils.blank,
            action: {},
            afterOne: utils.blank,
            after: utils.blank,
            childrenRoutes: {},
            childrenRoute: childrenRoute
        },
        _OldHash = "";
    plan.routes = {};
    plan.url = url;

    var route = function(routename, route) {
        addRoute(plan.routes, routename, route);
        return route;
    };

    window.onhashchange = function(event) {
        changeRoute();
    };

    function changeRoute() {
        var oldHash = _OldHash.substring(2),
            nowHash = location.hash.substring(2),
            context = {};
        if (oldHash === nowHash) {
            return;
        }
        _OldHash = location.hash;
        var paths = parseHash(nowHash).path.split("/"),
            oldPaths = parseHash(oldHash).path.split("/");
        oldPaths.pop();
        callRoute(plan.routes, paths, 0, null, oldPaths, context);
    }

    function redirect(url) {
        if (typeof url !== 'undefined') {
            location.hash = '#' + url;
        }

        changeRoute();
    }
    plan.redirect = redirect;
    plan.search = function(params) {
        var currentHash = location.hash;
        var urlObjs = parseHash(currentHash);
        if (typeof params === 'undefined') {
            return urlObjs.search;
        } else {
            location.hash = createUrl(urlObjs.path, params, urlObjs.search);
        }
    };
    plan.path = function(path, params) {
        var currentHash = location.hash;
        var urlObjs = parseHash(currentHash);
        if (typeof path === 'undefined') {
            return urlObjs.path;
        } else {
            params = params || {};
            location.hash = createUrl(path, params, urlObjs.search);
        }
    };
    plan.replace = function() {

    };
    plan.route = route;
    /**
     * [url 改变当前浏览器的url路径，并且清除get参数]
     * @param  {[string]} url    [url路径]
     * @param  {[object]} params [get参数]
     * @return {[plan]}        [返回plan对象]
     */
    function url(url, params, title) {
        if (typeof path === 'undefined') {
            return location.hash;
        } else {
            params = params || {};
            location.hash = createUrl(url, params);
        }
    }
    /**
     * [parseHash 将url格式化成路径和参数]
     * @pamam {[string]} url[url地址]
     * @return {[object]} url 对象
     */
    function parseHash(hash) {
        var splitIndex = hash.indexOf("?");
        splitIndex = splitIndex == -1 ? hash.length : splitIndex;
        var path = hash.substring(0, splitIndex),
            getparams = hash.substring(splitIndex);

        var tempParams = getparams.split("&"),
            params = {};
        for (var i = 0, len = tempParams.length; i < len; i++) {
            var tempParam = tempParams[0].split("=");
            params[decodeURIComponent(tempParam[0])] = decodeURIComponent(tempParam[1]);
        }
        return {
            path: path,
            search: params
        };
    }
    /**
     * [createUrl 根据path路径和get参数生成url路径]
     * @param  {[string]} path         [path路径]
     * @param  {[object]} params       [新的get参数]
     * @param  {[object]} appendParams [旧的get参数]
     * @return {[string]}              [最后的结果url]
     */
    function createUrl(path, params, appendParams) {
        if (typeof appendParams !== 'undefined') {
            utils.extend(params, appendParams);
        }
        var getparams = [];
        for (var i in params) {
            getparams.push(i + "=" + params[i]);
        }
        getparams = getparams.join("&");
        return path.indexOf("?") > -1 ? path + "&" + getparams : path + "?" + getparams;
    }

    function addRoute(routeContainer, routename, route) {
        routeContainer[routename] = utils.extend(route, templateRoute);
    }

    function childrenRoute(routename, route) {
        this.childrenRoutes[routename] = utils.extend(route, templateRoute);
        return route;
    }

    function callRoute(routeContainer, paths, i, parentRoute, oldPaths, context) {
        if (i == paths.length - 1) { //如果是最后一个，那就是action,直接执行
            parentRoute.action[paths[i]]();
            return;
        }
        var routename = paths[i],
            route = routeContainer[routename],
            beforeOneValue = null;
        // 和之前路径进行匹配，没有匹配上的话就执行beforeOne,afterOne
        if (oldPaths.slice(0, i + 1).join("/") !== paths.slice(0, i + 1).join("/")) {
            beforeOneValue = route.beforeOne(context);
        }
        if (utils.isPromise(beforeOneValue)) {
            beforeOneValue.then(function(value) {
                callRoute(route.childrenRoutes, paths, ++i, route, oldPaths, context);
            });
        } else {
            callRoute(route.childrenRoutes, paths, ++i, route, oldPaths, context);
        }
    }
});
